import { Context } from 'koa';
import { Prisma } from '@prisma/client';
import { logger } from '../utils/logger';
import { UserService } from '../services/user.service';

interface UserQuery {
  page?: number;
  limit?: number;
}

export async function getUsers(ctx: Context) {
  const query = ctx.state.validatedQuery as UserQuery;

  try {
    const { users, total } = await UserService.findMany(query);
    const { page = 1, limit = 10 } = query;

    ctx.body = {
      status: 'success',
      data: {
        users,
        pagination: {
          page,
          limit,
          total,
          pages: Math.ceil(total / limit),
        },
      },
    };
  } catch (error) {
    logger.error('Error fetching users:', error);
    throw error;
  }
}

export async function getUser(ctx: Context) {
  const { id } = ctx.params;

  try {
    const user = await UserService.findById(Number(id));

    if (!user) {
      ctx.status = 404;
      ctx.body = {
        status: 'error',
        message: 'User not found',
      };
      return;
    }

    ctx.body = {
      status: 'success',
      data: user,
    };
  } catch (error) {
    logger.error('Error fetching user:', error);
    throw error;
  }
}

export async function createUser(ctx: Context) {
  const userData = ctx.state.validatedBody;

  try {
    const user = await UserService.create(userData);

    ctx.status = 201;
    ctx.body = {
      status: 'success',
      data: user,
    };
  } catch (err) {
    if (err instanceof Prisma.PrismaClientKnownRequestError) {
      if (err.code === 'P2002') {
        ctx.status = 409;
        ctx.body = {
          status: 'error',
          message: 'Email already exists',
        };
        return;
      }
    }
    logger.error('Error creating user:', err);
    throw err;
  }
}

export async function updateUser(ctx: Context) {
  const { id } = ctx.params;
  const updateData = ctx.state.validatedBody;

  try {
    const user = await UserService.update(Number(id), updateData);

    ctx.body = {
      status: 'success',
      data: user,
    };
  } catch (err) {
    if (err instanceof Prisma.PrismaClientKnownRequestError) {
      if (err.code === 'P2025') {
        ctx.status = 404;
        ctx.body = {
          status: 'error',
          message: 'User not found',
        };
        return;
      }
      if (err.code === 'P2002') {
        ctx.status = 409;
        ctx.body = {
          status: 'error',
          message: 'Email already exists',
        };
        return;
      }
    }
    logger.error('Error updating user:', err);
    throw err;
  }
}

export async function deleteUser(ctx: Context) {
  const { id } = ctx.params;

  try {
    await UserService.delete(Number(id));
    ctx.status = 204;
  } catch (err) {
    if (err instanceof Prisma.PrismaClientKnownRequestError) {
      if (err.code === 'P2025') {
        ctx.status = 404;
        ctx.body = {
          status: 'error',
          message: 'User not found',
        };
        return;
      }
    }
    logger.error('Error deleting user:', err);
    throw err;
  }
}
